#ifndef RENDERER_H
#define RENDERER_H

#include <map>
#include <memory>
#include <string>
#include <vector>

#include <gl/glew.h>
#define GLFW_DLL
#include <gl/glfw.h>

#include "renderer/font.h"

class Camera;
class EntityRenderer;
class GuiRenderer;
class SubRenderer;
class TerrainRenderer;


enum RenderMode{ RM_DRAW, RM_PICK };

class Renderer{
    public:
        Renderer();
        void Initialise();
        void Kill();
        void Resize(int w, int h);
        void ProcessKey(int key);
        static void GLFWCALL ResizeCallback(int w, int h);

        int Pick(int x, int y);
        void Draw();

        int GetHeight(){ return sceney; }
        int GetWidth(){ return scenex; }

        Font* GetFont(){ return font; }

        void RefreshTerrain();

    private:
        GLuint CreateShader(GLenum eShaderType, const std::string &strShaderFile);
        GLuint CreateProgram(const std::vector<GLuint> &shaderList);

        void LoadTerrain();
        void BuildTerrainData();

		std::shared_ptr<TerrainRenderer> terrainRenderer;
		std::shared_ptr<EntityRenderer> entityRenderer;
		std::shared_ptr<GuiRenderer> guiRenderer;
		std::vector<std::shared_ptr<SubRenderer>> subRenderers;

		bool picking;
		int scenex, sceney;

        void SetupPickingFramebuffer();

        GLuint pickingFBO;

		Camera* camera;

		int width;
		int height;
		float frustumScale;
		float zNear;
		float zFar;

		RenderMode renderMode;

		Font* font;
};

extern Renderer *renderer;

#endif
